Add support for sending event channel interrupts to HVM guests.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 10 Aug 2006 10:36:27 +0000 (11:36 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 10 Aug 2006 10:36:27 +0000 (11:36 +0100)
Signed-off-by: Steven Smith <ssmith@xensource.com>
xen/arch/x86/hvm/svm/intr.c
xen/arch/x86/hvm/vmx/io.c

index fbcf60632f220692071ce2acd8e6f53455438f2f..a2767df2ed72c1b2266b259e8651111a371c1b30 100644 (file)
@@ -112,6 +112,7 @@ asmlinkage void svm_intr_assist(void)
     struct hvm_domain *plat=&v->domain->arch.hvm_domain; 
     struct periodic_time *pt = &plat->pl_time.periodic_tm;
     struct hvm_virpic *pic= &plat->vpic;
+    int callback_irq;
     int intr_type = APIC_DM_EXTINT;
     int intr_vector = -1;
     int re_injecting = 0;
@@ -156,12 +157,22 @@ asmlinkage void svm_intr_assist(void)
       if ( v->vcpu_id == 0 )
          hvm_pic_assist(v);
 
-      /* Before we deal with PIT interrupts, let's check
-         for interrupts set by the device model.
+      callback_irq = v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+
+      /* Before we deal with PIT interrupts, let's check for
+         interrupts set by the device model or paravirtualised event
+         channel interrupts.
       */
       if ( cpu_has_pending_irq(v) ) {
            intr_vector = cpu_get_interrupt(v, &intr_type);
       }
+      else  if ( callback_irq != 0 && local_events_need_delivery() ) {
+          /*inject para-device call back irq*/
+          v->vcpu_info->evtchn_upcall_mask = 1;
+          pic_set_irq(pic, callback_irq, 0);
+          pic_set_irq(pic, callback_irq, 1);
+          intr_vector = callback_irq;
+      }
       else  if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr ) {
           pic_set_irq(pic, pt->irq, 0);
           pic_set_irq(pic, pt->irq, 1);
index fee2c66bee7fc853dba0f4141c2424ea53bc5df3..0d8390e7921a8b689f0ab3258e6d66424300429c 100644 (file)
@@ -142,6 +142,7 @@ asmlinkage void vmx_intr_assist(void)
     struct hvm_domain *plat=&v->domain->arch.hvm_domain;
     struct periodic_time *pt = &plat->pl_time.periodic_tm;
     struct hvm_virpic *pic= &plat->vpic;
+    int callback_irq;
     unsigned int idtv_info_field;
     unsigned long inst_len;
     int    has_ext_irq;
@@ -154,6 +155,15 @@ asmlinkage void vmx_intr_assist(void)
         pic_set_irq(pic, pt->irq, 1);
     }
 
+    callback_irq = v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+    if ( callback_irq != 0 &&
+         local_events_need_delivery() ) {
+        /*inject para-device call back irq*/
+        v->vcpu_info->evtchn_upcall_mask = 1;
+        pic_set_irq(pic, callback_irq, 0);
+        pic_set_irq(pic, callback_irq, 1);
+    }
+
     has_ext_irq = cpu_has_pending_irq(v);
 
     if (unlikely(v->arch.hvm_vmx.vector_injected)) {